package com.postracker.postracker.db.action.init;

import java.util.Collections;
import java.util.List;

import org.apache.commons.lang.StringUtils;

import com.postracker.postracker.db.action.TableRow;
import com.postracker.postracker.db.exception.DBInitializationException;
import com.postracker.postracker.util.ArrayUtils;

public class InbsertTableRow implements TableRow {

	private static final String QUOTE = "'";

	private String sortedColumns[];
	private String sortedValues[];
	private String tableName;

	protected InbsertTableRow() {
		// Nothing to do. Just limiting the creation scope
	}

	@Override
	public void setSortedValues(String[] values) {
		this.sortedValues = values.clone();
	}

	private String getInsertStatement() {
		prepareValuesToSql();
		StringBuilder sb = new StringBuilder();
		sb.append("insert into ").append(tableName).append(" (");
		sb = ArrayUtils.getInstance()
				.addCommaSeparatedValues(sortedColumns, sb);
		sb.append(") values( ");
		sb = ArrayUtils.getInstance().addCommaSeparatedValues(sortedValues, sb);
		sb.append(")");
		return sb.toString();
	}

	private void prepareValuesToSql() {
		assertTableNameNotEmpty();
		assertSameNumberOfColumnsAndValues();
		for (int i = 0; i < sortedColumns.length; i++) {
			sortedValues[i] = addQuotesIfRequired(sortedValues[i]);
		}
	}

	private void assertTableNameNotEmpty() {
		if (StringUtils.isEmpty(tableName)) {
			throw new DBInitializationException(
					"A table name must be setted before getting the statements");
		}
	}

	private void assertSameNumberOfColumnsAndValues() {
		if (sortedColumns.length != sortedValues.length) {
			throw new DBInitializationException("Unexpected number of values.");
		}

	}

	private String addQuotesIfRequired(String value) {
		if (containsOnlyNumbers(value)) {
			return value;

		}
		StringBuilder sb = new StringBuilder(QUOTE);
		sb.append(value).append(QUOTE);
		return sb.toString();
	}

	private boolean containsOnlyNumbers(String string) {
		return string.matches("\\d+");
	}

	@Override
	public List<String> getStatements() {
		return Collections.singletonList(getInsertStatement());
	}

	@Override
	public void setSortedColumns(String[] sortedColumns) {
		this.sortedColumns = sortedColumns.clone();
	}

	@Override
	public void setTableName(String tableName) {
		this.tableName = tableName;
	}

}
